package com.turtle.service.impl;

import com.turtle.aop.RedissonLock;
import com.turtle.constant.SysConf;
import com.turtle.dto.BlogInfoDto;
import com.turtle.dto.BlogParam;
import com.turtle.dto.PageEntity;
import com.turtle.entity.sql.Blog;
import com.turtle.exception.UserAlertException;
import com.turtle.extend.BlogConverter;
import com.turtle.mapper.BlogMapper;
import com.turtle.send.RabbitSender;
import com.turtle.service.BlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lijiayu
 * @date 2020/7/20
 * @description
 */
@Service
public class BlogServiceImpl implements BlogService {

    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private BlogConverter blogConverter;
    @Autowired
    private RabbitSender rabbitSender;

    /**
     * 保存博客
     * @param param
     * @param userId
     */
    @Override
    @Transactional
    public void add(BlogParam param,Long userId) {
        Blog blog = blogConverter.toEntity(param,userId);
        blogMapper.insert(blog);

        //通知es
        Map<String,Object> map = new HashMap<>();
        map.put(SysConf.TYPE,SysConf.ADD);
        map.put("id", blog.getId());
        rabbitSender.sendBlog(map);
    }

    /**
     * 编辑博客
     * @param param
     */
    @Override
    @RedissonLock(key = "#param.id")
    @Transactional(rollbackFor = Exception.class)
    public void update(BlogParam param,Long userId) {
        Blog oldBlog = Optional.ofNullable(blogMapper.selectById(param.getId()))
                .orElseThrow(() -> new UserAlertException("找不到对应的博客"));
        if(!oldBlog.getUserId().equals(userId)){
            throw new UserAlertException("博客与用户不匹配");
        }

        Blog blog = blogConverter.toEntity(param,userId);
        blogMapper.updateById(blog);

        //通知es
        Map<String,Object> map = new HashMap<>();
        map.put(SysConf.TYPE,SysConf.UPDATE);
        map.put("id", blog.getId());
        rabbitSender.sendBlog(map);

    }

    @Override
    public void delete(Long id, Long userId) {
        Blog oldBlog = Optional.ofNullable(blogMapper.selectById(id))
                .orElseThrow(() -> new UserAlertException("博客已被删除"));
        if(!oldBlog.getUserId().equals(userId)){
            throw new UserAlertException("博客与用户不匹配");
        }

        //通知es
        Map<String,Object> map = new HashMap<>();
        map.put(SysConf.TYPE,SysConf.DELETE);
        map.put("id", id);
        rabbitSender.sendBlog(map);
    }

    @Override
    public PageEntity<Blog> getPage() {
        return null;
    }

    /**
     * 获取博客信息
     * @param id
     * @param userId
     * @return
     */
    @Override
    public BlogInfoDto getInfoById(Long id, Long userId) {
        Blog blog = Optional.ofNullable(blogMapper.selectById(id))
                .orElseThrow(() -> new UserAlertException("找不到对应的博客"));
        //走rpc可能存在userId为null
        if(userId != null&&!blog.getUserId().equals(userId)){
            throw new UserAlertException("博客与用户不匹配");
        }
        return blogConverter.toDto(blog);
    }

    /**
     * 获取用户下各分类的文章数
     * @param userId
     * @return
     */
    @Override
    public Map<Long, Long> getCountMapByUserId(Long userId) {
        List<Blog> blogs = blogMapper.selectListByUserIdAndStatus(userId, null);
        return blogs.stream().filter(blog -> blog.getBlogSortId()!=null)
                .collect(Collectors.groupingBy(Blog::getBlogSortId,Collectors.counting()));
    }
}
